#include "register_login.h"
#include "mysql.h"

// 判断登录还是注册
int log_Or_reg(int netfd, MysqlPool_t *mysql_pool)
{
    // char buffer[1024];
    int choice = 0;
    train_t train;
    while (1)
    {
        bzero(&train, sizeof(train));
        // 接收客户端发送的选择（1登录 或 2注册）
        int ret = recv_n(netfd, &train.train_len, sizeof(train.train_len));
        ERROR_CHECK(ret, -1, "recv_n");
        LOG_INFO("recv train_len = %d\n", train.train_len);
        ret = recv_n(netfd, train.train_data, train.train_len);
        ERROR_CHECK(ret, -1, "recv_n");
        memcpy(&choice, train.train_data, sizeof(choice));
        LOG_INFO("recv choice = %d\n", choice);
        // 根据选择执行相应的操作

        if (choice == 1)
        {
            // 登录
            LOG_INFO("user choose login\n");
            int login_status = 0;
            login_user(netfd, mysql_pool, &login_status); // 登录用户
            if (login_status == 1){
                LOG_INFO("login success\n");
                break;
            }
            continue;
        }
        else if (choice == 2)
        {
            // 注册
            LOG_INFO("user choose register\n");
            register_user(netfd, mysql_pool);
        }
        else
        {
            LOG_INFO("user choose error\n");
            return -1;
        }
    }
    return 0;
}
// 注册用户
int register_user(int netfd, MysqlPool_t *mysql_pool)
{
    train_t train;
    bzero(&train, sizeof(train));
    char username[128] = {0};
    char password[128] = {0};
    // 接收用户名
    int ret = recv_n(netfd, &train.train_len, sizeof(train.train_len));
    ERROR_CHECK(ret, -1, "recv_n");
    LOG_INFO("recv train_len = %d\n", train.train_len);
    ret = recv_n(netfd, train.train_data, train.train_len);
    ERROR_CHECK(ret, -1, "recv_n");
    memcpy(username, train.train_data, train.train_len);
    LOG_INFO("recv username = %s\n", username);
    // 接收密码
    ret = recv_n(netfd, &train.train_len, sizeof(train.train_len));
    ERROR_CHECK(ret, -1, "recv_n");
    LOG_INFO("recv train_len = %d\n", train.train_len);
    ret = recv_n(netfd, train.train_data, train.train_len);
    ERROR_CHECK(ret, -1, "recv_n");
    memcpy(password, train.train_data, train.train_len);
    LOG_INFO("recv password ");
    // 密码加密
    char hex_salt[SALT_LENGTH * 2 + 1] = {0};
    char hex_hash[SHA256_DIGEST_LENGTH * 2 + 1] = {0};
    encrypt_password(password, hex_salt, sizeof(hex_salt), hex_hash, sizeof(hex_hash));
    LOG_INFO("encrypt password success\n");
    LOG_INFO("hex_salt = %s\n", hex_salt);
    LOG_INFO("hex_hash = %s\n", hex_hash);
    // 将用户名和加密后的密码插入数据库
    MYSQL *mysql = mysql_pool_get(mysql_pool);
    char sql[1024] = {0};
    sprintf(sql, "INSERT INTO users (username, password_hash, salt) VALUES ('%s', '%s', '%s')", username, hex_hash, hex_salt);
    LOG_INFO("sql = %s\n", sql);
    ret = mysql_query(mysql, sql);
    mysql_commit(mysql);

    // ERROR_CHECK(ret, -1, "mysql_query");
    if (ret != 0)
    {
        LOG_ERROR("mysql_query error: %s", mysql_error(mysql));
    }
    mysql_pool_release(mysql_pool, mysql);
    // 发送注册成功的消息
    bzero(&train, sizeof(train));
    train.train_len = strlen("register success");
    memcpy(train.train_data, "register success", train.train_len);
    ret = send(netfd, &train, sizeof(train.train_len) + train.train_len, 0);
    ERROR_CHECK(ret, -1, "send");
    LOG_INFO("send register success to client\n");
    // login_user(netfd, mysql_pool);
    return 0;
}
// 登录用户
int login_user(int netfd, MysqlPool_t *mysql_pool, int *login_status)
{
    train_t train;
    bzero(&train, sizeof(train));
    char username[128] = {0};
    char password[128] = {0};
    // 接收用户名
    int ret = recv_n(netfd, &train.train_len, sizeof(train.train_len));
    ERROR_CHECK(ret, -1, "recv_n");
    LOG_INFO("recv train_len = %d\n", train.train_len);
    ret = recv_n(netfd, train.train_data, train.train_len);
    ERROR_CHECK(ret, -1, "recv_n");
    memcpy(username, train.train_data, train.train_len);
    LOG_INFO("recv username = %s\n", username);
    // 接收密码
    ret = recv_n(netfd, &train.train_len, sizeof(train.train_len));
    ERROR_CHECK(ret, -1, "recv_n");
    LOG_INFO("recv train_len = %d\n", train.train_len);
    ret = recv_n(netfd, train.train_data, train.train_len);
    ERROR_CHECK(ret, -1, "recv_n");
    memcpy(password, train.train_data, train.train_len);
    LOG_INFO("recv password ");
    // 验证用户名和密码
    char sql[1024] = {0};
    MYSQL *mysql = mysql_pool_get(mysql_pool);
    sprintf(sql, "SELECT password_hash, salt FROM users WHERE username = '%s'", username);
    LOG_INFO("sql = %s\n", sql);
    ret = mysql_query(mysql, sql);
    ERROR_CHECK(ret, -1, "mysql_query");
    MYSQL_RES *res = mysql_store_result(mysql);
    if (res == NULL)
    {
        // 没有找到用户, 发送登录失败的消息0
        LOG_INFO("user not found\n");
        int is_login = 0;
        *login_status = is_login;
        bzero(&train, sizeof(train));
        train.train_len = sizeof(int);
        memcpy(train.train_data, &is_login, train.train_len);
        ret = send(netfd, &train, sizeof(train.train_len) + train.train_len, 0);
        ERROR_CHECK(ret, -1, "send");
        LOG_INFO("send login failed to client\n");
        mysql_pool_release(mysql_pool, mysql);
        return 0;
    }
    else
    {
        // 拿到用户信息
        MYSQL_ROW row = mysql_fetch_row(res);
        if (row == NULL)
        {
            // 没有找到用户
            LOG_INFO("user not found\n");
            int is_login = 0;
            *login_status = is_login;
            bzero(&train, sizeof(train));
            train.train_len = sizeof(int);
            memcpy(train.train_data, &is_login, train.train_len);
            ret = send(netfd, &train, sizeof(train.train_len) + train.train_len, 0);
            ERROR_CHECK(ret, -1, "send");

            mysql_free_result(res);
            mysql_pool_release(mysql_pool, mysql);
            return 0;
        }
        else
        {
            // 找到用户
            char stored_hash[SHA256_DIGEST_LENGTH * 2 + 1] = {0};
            char stored_salt[SALT_LENGTH * 2 + 1] = {0};
            memcpy(stored_hash, row[0], strlen(row[0]));
            memcpy(stored_salt, row[1], strlen(row[1]));
            LOG_INFO("stored_hash = %s\n", stored_hash);
            LOG_INFO("stored_salt = %s\n", stored_salt);
            char hex_hash[SHA256_DIGEST_LENGTH * 2 + 1] = {0};
            // encrypt_password(password, stored_salt, sizeof(stored_salt), hex_hash, sizeof(hex_hash));
            if (!verify_password(password, stored_salt, stored_hash))
            {
                LOG_INFO("password error\n");
                int is_login = 0;
                *login_status = is_login;
                bzero(&train, sizeof(train));
                train.train_len = sizeof(int);
                memcpy(train.train_data, &is_login, train.train_len);
                ret = send(netfd, &train, sizeof(train.train_len) + train.train_len, 0);
                ERROR_CHECK(ret, -1, "send");
                LOG_INFO("send login failed to client\n");
                mysql_pool_release(mysql_pool, mysql);
                return 0;
            }
            LOG_INFO("encrypt password success\n");
            LOG_INFO("hex_hash = %s\n", hex_hash);

            // 密码匹配
            int is_login = 1;
            *login_status = is_login;
            LOG_INFO("login success\n");
            bzero(&train, sizeof(train));
            train.train_len = sizeof(int);
            memcpy(train.train_data, &is_login, train.train_len);
            ret = send(netfd, &train, sizeof(train.train_len) + train.train_len, 0);
            ERROR_CHECK(ret, -1, "send");
            LOG_INFO("send login success to client\n");
            mysql_pool_release(mysql_pool, mysql);
            add_session(netfd, username, -1);
            // 发送第一条显示的文件列表
            bzero(&train, sizeof(train));
            train.train_len = strlen("/");
            strcpy(train.train_data, "/");
            ret = send(netfd, &train, sizeof(train.train_len) + train.train_len, 0);
            ERROR_CHECK(ret, -1, "send");
            LOG_INFO("send first file list to client\n");

            return 1;

            // else
            // {
            //     // 密码不匹配
            //     LOG_INFO("password error\n");
            //     int is_login = 0;
            //     bzero(&train, sizeof(train));
            //     train.train_len = sizeof(int);
            //     memcpy(train.train_data, &is_login, train.train_len);
            //     ret = send(netfd, &train, sizeof(train.train_len) + train.train_len, 0);
            //     ERROR_CHECK(ret, -1, "send");
            //     LOG_INFO("send login failed to client\n");
            //     mysql_pool_release(mysql_pool, mysql);
            //     return 0;
            // }
        }
    }
    return 0;
}
